<!--
 * @Author: adolphus adolphus520@163.com
 * @Date: 2022-12-04 12:28:32
 * @LastEditors: 姚杰鸿
 * @LastEditTime: 2024-07-24 16:00:15
 * @Description: file content
-->
<template>
  <el-select-v2
    v-model="selValue"
    filterable
    :placeholder="placeholder"
    :options="icons"
    clearable
    value-key="k"
    @change="change"
  >
    <template #default="{ item }">
      <div class="flex items-center">
        <el-tag style="margin-right: 8px" size="small">
          <font-awesome-icon :class="['icon']" :icon="item.value.v" />
        </el-tag>
        <span>{{ item.label }}</span>
      </div>
    </template>
    <template #label>
      <el-tag style="margin-right: 8px" size="small">
        <font-awesome-icon :class="['icon']" :icon="selValue?.v" />
      </el-tag>
      <span>{{ selValue?.k }}</span>
    </template>
  </el-select-v2>
</template>

<script lang="ts">
export interface IconOption {
  k: string;
  v: IconDefinition;
}
</script>

<script lang="ts" setup>
import { ref, toRef, defineEmits, defineProps, watch, PropType } from "vue";

import type { OptionType } from "element-plus/es/components/select-v2/src/select.types";
import {
  fas,
  IconPack,
  IconDefinition,
} from "@fortawesome/free-solid-svg-icons";
import { far } from "@fortawesome/free-regular-svg-icons";
import { fab } from "@fortawesome/free-brands-svg-icons";

const props = defineProps({
    value: {
      type: String,
      default: "",
    },
    placeholder: {
      type: String,
      default: "Select Icon",
    },
  }),
  selValue = ref<IconOption>(),
  emit = defineEmits(["update:value", "change"]);

const convertIconPackToOptions = (iconPack: IconPack): OptionType[] => {
    const options: OptionType[] = [];
    let i = 0;
    for (const key in iconPack) {
      options.push({
        label: key,
        value: {
          k: key,
          v: iconPack[key],
        },
      });
    }
    return options;
  },
  change = (v: any) => {
    let d = "";
    if (v) d = v.k + ":" + v.v.prefix + " " + v.v.iconName;
    emit("update:value", d);
    emit("change", d);
  };

const icons = ref([
  {
    value: "solid",
    label: "solid",
    options: convertIconPackToOptions(fas),
  },
  {
    value: "regular",
    label: "regular",
    options: convertIconPackToOptions(far),
  },
  {
    value: "brands",
    label: "brands",
    options: convertIconPackToOptions(fab),
  },
]);

watch(
  () => props.value,
  (newValue) => {
    const k = newValue.split(":")[0];
    if (fas[k]) {
      selValue.value = {
        k: k,
        v: fas[k],
      };
    } else if (far[k]) {
      selValue.value = {
        k: k,
        v: far[k],
      };
    } else if (fab[k]) {
      selValue.value = {
        k: k,
        v: fab[k],
      };
    } else {
      selValue.value = ref().value;
    }
  }
);
</script>

<style lang="scss" scoped>
.el-icon-picker {
  height: 256px;
  overflow-y: scroll;
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
}

.icon {
  display: inline-block;
  width: 24px;
  height: 24px;
  color: var(--el-text-color-regular);
  font-size: 20px;
  border-radius: 4px;
  cursor: pointer;
  text-align: center;
  line-height: 45px;
  margin: 5px;
}

.icon:hover {
  color: var(--el-color-primary);
}

.icon-active {
  color: var(--el-color-primary);
}

.el-tag {
  border: none;
  aspect-ratio: 1;
}
</style>
